/*
 * =====================================================================================
 *       Filename:  config.c
 *    Description:  配置相关代码
 *        Created:  2015-07-04 12:52
 *         Author:  mien, m@p58.net
 * =====================================================================================
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>
#include <fcntl.h>
#include "config.h"

#include "dict.h"
#include "zipmap.h"

#define MAX_LINE_SIZE 1024

int _loaded = 0;
dictTable *_config;

void loadConfig(const char *filename)
{
    if (_loaded) return;

    _config = dictCreateWithSize(&dictTypeStringKeyVal, 32);

    FILE *fp = fopen(filename, "r");
    if (fp == NULL) return;
    
    char buf[MAX_LINE_SIZE];
    char line[MAX_LINE_SIZE];
    char section[32];
    
    while (fgets(buf, MAX_LINE_SIZE, fp) != NULL) {
        /* 复制buf中的行字符到line中，去掉空格 */
        int i, j, flag, len;
        j = 0;
        flag = -1;
        for (i = 0; i < MAX_LINE_SIZE; i++) {
            if (buf[i] == ' ') continue;
            if (buf[i] == '\n' || buf[i] == '\r' || buf[i] == '\0') {
                line[j++] = '\0';
                break;
            }
            if (buf[i] == '=')
                flag = j;
            line[j++] = buf[i];
        }
        
        /* 忽略空行、注释行 */
        if (j < 2 || line[0] == '#') continue;
        
        /* 忽略格式错误的小节标记行 */
        if ((line[0] == '[' && line[j - 2] != ']') || (line[0] != '[' && line[j - 2] == ']'))
            continue; 
        
        /* 忽略格式错误的设置项行 */
        if (line[0] != '[' && flag <= 0) continue;
        
        /* 是小节 */
        if (line[0] == '[') {
            strncpy(section, line + 1, j - 3);
            section[j - 3] = '\0';
        }
        /* 是设置项 */
        else {
            line[flag] = '\0';
            sprintf(buf, "%s_%s", section, line);
            dictSet(_config, buf, line + flag + 1);
        }
    }

    fclose(fp);
    _loaded = 1;
}

void freeConfig()
{
    dictFree(_config);
}

void setUidGid()
{
    char *user  = getConfig("user_user");
    char *group = getConfig("user_group");

    if (user != NULL) {
        struct passwd *pwd;
        pwd = getpwnam(user);
        if (pwd != NULL)
            setuid(pwd->pw_uid);
    }
    if (group != NULL) {
        struct group *grp;
        grp = getgrnam(group);
        if (grp != NULL)
            setgid(grp->gr_gid);
    }
}

char *getConfig(char *key)
{
    return dictGet(_config, key);
}
